好啦,昨天介紹完變數和常數,今天就從 Array 和 Hash 繼續下去吧!!
什麼?你說我還沒講資料型別?阿是不會自己去google 喔?
別急別急,讓我們慢慢看下去...
首先讓我們來看看下面這些陣列(Array):
a = ['What', 'I said is', 'is rubbish', 'everyone here']
b = [1, 2, 3]
c = [true, true, true, true, false]
d = ['懦夫救星', 28825252, true ]
嗯?好像有奇怪的東西混進程式碼裡面...暫時先不管他啦!
上面的 a, b, c, d 都是陣列,在Ruby 的世界,陣列裡面要放什麼,隨你高興。
你要都放字串,數字,或是boolean值,或是混在一起做成撒尿牛丸?,歡喜就好。
在Ruby 的世界裡,幾乎所有的東西都是物件,依照物件類別的不同,
會有不同的方法可以使用。
比如說:
a = ['What', 'I said is', 'is rubbish', 'everyone here']
a.length
=> 4
a[0]
=> "What"
a[3]
=> "everyone here"
a[-1]
=> "everyone here"
a[-4]
=> "What"
a[-5]
=> nil
相信眼尖的你應該有發現,沒錯:
在Ruby 的世界裡index 可以是負數,會自動幫你從最後一個元素倒著數。
a.reverse
=>["everyone here", "is rubbish", "I said is", "What"]
還記得昨天提到的 each 嗎? 他其實是Array可以使用的方法之一;
下面我們就來進一步介紹幾個比較常用的方法:
首先,來試著選出 陣列a 中所有的奇數。
就用昨天剛學會的 each 來試試看吧!
寫起來大概會像這樣:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = []
a.each do |i|
b << i if i % 2 == 1
end
p b # [1, 3, 5, 7, 9]
如果改用select來寫呢?
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
p a.select {|i| i % 2 == 1} # [1, 3, 5, 7, 9]
WTF?!!! 不不不,這是Ruby的日常喔!
稍微觀察一下,可以看出select的用法是這樣的:
array.select{|i| "篩選的條件"}
接著我們試著將 陣列[1, 2, 3, 4, 5] 變成 [2, 4, 6, 8, 10]。
一樣,先用 each 來做,寫起來會像是這樣:
c = [1, 2, 3, 4, 5]
d = []
c.each do |i|
d << i * 2
end
p d # [2, 4, 6, 8, 10]
那如果改用map寫呢?
c = [1, 2, 3, 4, 5]
p c.map{|i| i * 2} # [2, 4, 6, 8, 10]
WTF? 沒有剛剛那麼驚訝了吧?
聰明如你應該已經發現了:
如果你需要再迴圈外面定義一個變數,然後在迴圈裡面重複的取用他;
那在Ruby通常會有更簡單的寫法。
接著,我試著來計算1到10的總和吧!
老樣子,我們先用each來做:
total = 0
[*1..10].each do |i|
sum = sum + i
end
p sum # 55
看出端倪了嗎?換成reduce的話,可以寫成這樣:
p [*1..10].reduce(0) {|total,i| total + i} # 55
有看到奇怪的東西嗎?
[*1..10 ] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
*是建立Array的一種縮寫
此外還有一個需要注意的地方:
reduce(0) ,括號裡面的 0 ,是我們給total設定的初始值,它的作用和用each的寫法時,
在外面寫的 total = 0 一樣。
p [*1..10].reduce {|total,i| total + i} # 55
當你沒有設定初始值, reduce方法,會自己拿第一個元素作為初始值,在這個例子裡就是 1 。
可以透過下面的程式碼觀察兩者的差異:
[*1..10].reduce(0){|total,i| p (total + i) } # 1, 3, ... 45, 55
[*1..10].reduce{|total,i| p (total + i) } # 3, ... 45, 55
公堂之上假設一下,我想是無傷大雅的
假設我們有一籃水果,裡面有蘋果5個,香蕉3個,芒果4個。
下面三種寫法的意思都是一樣的:
basket = { "apple" => 5, "banana" => 3, "mango" => 4 }
basket = { :apple => 5, :banana => 3, :mango => 4 }
basket = { apple: 5, banana: 3, mango: 4 }
在 basket 這個 hash 當中:
"apple"、"banana" 和 "mango",我們稱之為key
5、3和4,我們稱之為value
但是,當你想知道蘋果有幾個的時候:
basket[:apple] #只有這樣才拿得到值
=> 5
這裡的 :apple 他是一個符號(symbol)
each 也是 Hash 可以使用的方法之一喔!
所以我們可以這樣做:
basket.each { |i| p i }
#印出
# ["apple", 5]
# ["banana", 3]
# ["mango", 4]
你也可以像下面這樣
basket.each {|k,v| p "Key is #{k}, Value is #{v}"}
#印出
#"Key is apple, Value is 5"
#"Key is banana, Value is 3"
#"Key is mango, Value is 4"
或者,你也可以用 keys 和 values 的方法,只取出其中一項:
basket.keys
=> ["apple", "banana", "mango"]
basket.values
=> [5, 3, 4]
好,今天的鐵人賽就到這邊告一個段落,明天見!